package com.augurit.wf.bi.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.model.Activity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springside.modules.orm.Page;

import com.augurit.common.base.action.BaseAction;
import com.augurit.common.base.action.CrudActionSupport;
import com.augurit.common.base.action.ExtBaseAction;
import com.augurit.common.base.action.ExtCrudActionSupport;
import com.augurit.common.base.extmodel.BasicCombo;
import com.augurit.common.base.extmodel.ExtResult;
import com.augurit.common.sysmeta.web.form.SysMetaTableForm;
import com.augurit.common.util.ExtUtils;
import com.augurit.common.util.lang.StringUtils;
import com.augurit.wf.bi.service.IWfBusTemplateService;
import com.augurit.wf.bi.web.form.WfBusTemplateForm;
import com.augurit.wf.common.extmodel.ProcessReleaseTreeNode;
import com.augurit.wf.common.extmodel.ProcessVersionTreeNode;
import com.augurit.wf.common.extmodel.ProcessViewTreeNode;
import com.augurit.wf.common.service.IWfService;
import com.augurit.wf.common.util.WfUtils;
import com.augurit.wf.mgmt.convert.ConvertToExtModel;
import com.augurit.wf.mgmt.web.form.WfProcessDefForm;
import com.augurit.wf.mgmt.web.form.WfProcessVersionForm;

@SuppressWarnings("serial")
@Results({
	@Result(name = CrudActionSupport.RELOAD, location = "wf-bus-template.action", type = "redirect"),
	@Result(name = CrudActionSupport.SUCCESS, location = "/wf/bi/bus-template/bus-template-mgmt.jsp"),
	@Result(name = WfBusTemplateAction.DRAFT_VIEW, location = "/wf/client/common/draft-view.jsp")
})
public class WfBusTemplateAction extends ExtCrudActionSupport<WfBusTemplateForm>{

	public static final String DRAFT_VIEW = "DRAFT_VIEW";		//起草页面
	
	@Autowired
	private IWfBusTemplateService wfBusTemplateService;

	@Autowired
	private IWfService wfService;
	
	private WfBusTemplateForm form;
	private Long templateId;
	private Long[] templateIds;
	
	private Page<WfBusTemplateForm> page = new Page<WfBusTemplateForm>(10);
	private Long[] pageElementIds;
	
	
	/**
	 * 分页查询
	 */
	@Override
	public String list() throws Exception {
		ExtUtils.initPageFromExtGridParam(getRequest(), page);
		wfBusTemplateService.search(page, form);
		ExtBaseAction.extRenderGridJson(page);
		return null;
	}

	/**
	 * 新增或修改
	 */
	@Override
	public String input() throws Exception {
		ExtBaseAction.extRenderFormJson(form);
		return null;
	}

	
	/**
	 * 保存新增或者修改的Form对象
	 */
	@Override
	public String save() throws Exception {
		ExtResult extResult = new ExtResult();
		try{
			//保存业务流程模板
			wfBusTemplateService.saveAndShowRelatedEntitiesChanged(form);
			extResult.setMessage("{'templateId':" + form.getId() + "}");
			extResult.setSuccess(true);
			
			BaseAction.renderJson(extResult);
		}
		catch(Exception e){
			e.printStackTrace();
			extResult.setSuccess(false);
			extResult.setMessage("新增或者修改模板的基本信息失败！");
			BaseAction.renderJson(extResult);
		}
		return null;
	}

	/**
	 * 删除一条记录
	 */
	@Override
	public String delete() throws Exception {
		try{
			wfBusTemplateService.deleteCascade(templateId);
			ExtBaseAction.extRenderSuccess();
		}
		catch(Exception e){
			e.printStackTrace();
			ExtBaseAction.extRenderFailture();
		}
		return null;
	}
	
	
	/**
	 * 获取所有的流程key
	 * @return
	 * @throws Exception
	 */
//	public String getProcessKeyList()throws Exception {
//		//获取流程定义，忽略版本信息
//		List<ProcessDefinition> list= wfService.getProcDefIgnoreVersion();
//		
//		//转换
//		List<WfProcessDefForm> results = ConvertToExtModel.convertProcDefListToSimpleFormList(list);
//		
//		ExtBaseAction.extRenderListJson(results, true);
//		return null;
//	}
	
	/**
	 * 获取流程版本号
	 * @return
	 * @throws Exception
	 */
	public String getProcessVersionForTemplate()throws Exception {
		List<BasicCombo> nodes = new ArrayList<BasicCombo>();
		if(StringUtils.isNotBlank(form.getWfDefKey())){
			List<ProcessDefinition> list= wfService.getProcDefByProcDefKey(form.getWfDefKey());
			
			//提出流程定义的版本信息，转换下拉框
			nodes = ConvertToExtModel.convertToVersionSelectBox(list);
			
		}
		ExtBaseAction.extRenderListJson(nodes, true);
		return null;
	}
	
	//获取当前流程模板对应的流程的流程节点
	public String getActivities()throws Exception {
		String version = ExtBaseAction.getRequest().getParameter("version");
		List<? extends Activity> activities = wfService.getActivitiesByProcDefKeyAndVersion(form.getWfDefKey(), Integer.decode(version));
		List<BasicCombo> nodes = WfUtils.convertValidActivities(activities, true);
		ExtBaseAction.extRenderListJson(nodes, true);
		return null;
	}
	
	
	
	
	
	/**
	 * 删除模板中页面元素（注意：有两种情况：对于非公有页面元素，删除页面元素及关联；对于公有页面元素，删除模板与页面元素的关联） 
	 * @return
	 * @throws Exception
	 */
	public String deletePageElemFromTemplate() throws Exception {
		wfBusTemplateService.deletePageElemFromTemplate(templateId, pageElementIds);
		ExtBaseAction.extRenderSuccess();
		return null;
	}
	
	/**
	 * 获取与模板关联的业务实体表
	 * @return
	 * @throws Exception
	 */
	public String getRelatedEntities() throws Exception{
		List<SysMetaTableForm> result = wfBusTemplateService.getRelateEntities(templateId);
		ExtBaseAction.extRenderGridJson(result);
		return null;
	}
	
	/**
	 * 获取与模板关联的从实体表
	 * @return
	 * @throws Exception
	 */
	public String getSlaveEntites() throws Exception{
		List<SysMetaTableForm> result = wfBusTemplateService.getSlaveEntities(templateId);
		ExtBaseAction.extRenderGridJson(result);
		return null;
	}
	
	public String selectSlaveEntitesByMasterEntity() throws Exception{
		SysMetaTableForm sysMetaTableForm = new SysMetaTableForm();
		sysMetaTableForm.setEntityName(getRequest().getParameter("entityName"));
		sysMetaTableForm.setTableChineseComments(getRequest().getParameter("tableChineseComments"));
		List<SysMetaTableForm> result = wfBusTemplateService.selectSlaveEntitiesByMasterEntity(sysMetaTableForm, form.getMasterEntity());
		ExtBaseAction.extRenderGridJson(result);
		return null;
	}
	
	/**
	 * 根据业务流程模板id获取模板
	 * 修改日期：2011-04-13
	 * @return
	 * @throws Exception
	 */
	public String getVersionTreeWithViewByTemplateId() throws Exception{
		try{
			if(templateId == null)
				throw new NullPointerException("templateId 为空！");
			if(form.getWfDefKey() == null)
				throw new NullPointerException("wfDefKey 为空！");
			
			List<ProcessDefinition> list= wfService.getProcDefByProcDefKey(form.getWfDefKey());
			if(list == null || list.size() == 0)
				throw new NullPointerException("不能找到与wfDefKey对应的流程定义");
			
			List<ProcessReleaseTreeNode> result = new ArrayList<ProcessReleaseTreeNode>();
			for(ProcessDefinition processDef:list){
				ProcessReleaseTreeNode treeNode = new ProcessVersionTreeNode(false);
				
				if(processDef.getVersion() == form.getWfDefVersion().intValue())
					treeNode.setText(WfProcessVersionForm.formatToTheLatestVersion(processDef.getVersion()));
				else
					treeNode.setText(WfProcessVersionForm.formatVersion(processDef.getVersion()));
				
				treeNode.setType(ProcessReleaseTreeNode.VERSION_NODE);
				treeNode.setValue(String.valueOf(processDef.getVersion()));
				
				List<ProcessReleaseTreeNode> children = new ArrayList<ProcessReleaseTreeNode>();
				children.add(ProcessViewTreeNode.DZB_VIEW_NODE);
				children.add(ProcessViewTreeNode.YB_VIEW_NODE);
				children.add(ProcessViewTreeNode.BJ_VIEW_NODE);
				
				treeNode.setChildren(children);
				result.add(treeNode);
			}
			ExtBaseAction.extRenderListJson(result, false);
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 根据业务流程模板id获取模板
	 * 修改日期：2011-04-13
	 * @return
	 * @throws Exception
	 */
	public String getVersionTreeByTemplateId() throws Exception{
		try{
			if(templateId == null)
				throw new NullPointerException("templateId 为空！");
			
			List<ProcessReleaseTreeNode> result = new ArrayList<ProcessReleaseTreeNode>();
			if(form.getWfDefKey() != null){
				List<ProcessDefinition> list= wfService.getProcDefByProcDefKey(form.getWfDefKey());
				if(list == null || list.size() == 0)
					throw new NullPointerException("不能找到与wfDefKey对应的流程定义");
				
				
				for(ProcessDefinition processDef:list){
					ProcessReleaseTreeNode treeNode = new ProcessVersionTreeNode(true);
					
					if(processDef.getVersion() == form.getWfDefVersion().intValue())
						treeNode.setText(WfProcessVersionForm.formatToTheLatestVersion(processDef.getVersion()));
					else
						treeNode.setText(WfProcessVersionForm.formatVersion(processDef.getVersion()));
					
					treeNode.setType(ProcessReleaseTreeNode.VERSION_NODE);
					treeNode.setValue(String.valueOf(processDef.getVersion()));
					treeNode.setIconCls(ProcessReleaseTreeNode.CLS_PROCESS_VERSION);
					
					result.add(treeNode);
				}
			}
			ExtBaseAction.extRenderListJson(result, false);
			
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	public String getTemplateCode(){
		if(templateId != null){
			WfBusTemplateForm form = this.wfBusTemplateService.get(templateId);
			ExtBaseAction.renderText(form.getTemplateCode());
		}
		return null;
	}
	
	
	/**
	 * 准备页面模型
	 */
	@Override
	protected void prepareModel() throws Exception {
		if(templateId != null){
			form = wfBusTemplateService.get(templateId);
		}
		else
			form = new WfBusTemplateForm();
	}
	

	public WfBusTemplateForm getModel() {
		return form;
	}
	
	// 属性getter和setter方法
	public Page<WfBusTemplateForm> getPage() {
		return page;
	}


	public void setPage(Page<WfBusTemplateForm> page) {
		this.page = page;
	}

	public Long[] getPageElementIds() {
		return pageElementIds;
	}

	public void setPageElementIds(Long[] pageElementIds) {
		this.pageElementIds = pageElementIds;
	}

	public Long getTemplateId() {
		return templateId;
	}

	public void setTemplateId(Long templateId) {
		this.templateId = templateId;
	}

	public Long[] getTemplateIds() {
		return templateIds;
	}

	public void setTemplateIds(Long[] templateIds) {
		this.templateIds = templateIds;
	}
}
